package cn.doourbest.learnspring.config;

import cn.doourbest.learnspring.annotation.ControllerRegister;
import cn.doourbest.learnspring.inteceptor.PaginationStatementHandlerInterceptor;
import com.alibaba.druid.pool.DruidDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.postgresql.Driver;
import org.redisson.spring.session.config.EnableRedissonHttpSession;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.servlet.configuration.EnableWebMvcSecurity;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.*;
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
import org.springframework.security.oauth2.provider.client.InMemoryClientDetailsService;
import org.springframework.security.oauth2.provider.token.store.InMemoryTokenStore;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionException;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import javax.servlet.annotation.ServletSecurity;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Configuration
@ComponentScan("cn.doourbest")
@MapperScan(value = "cn.doourbest.learnspring.dao",sqlSessionFactoryRef = "newSqlSessionFactory")
@EnableAspectJAutoProxy
@EnableWebMvc
@EnableWebSecurity
//@EnableTransactionManagement
//@Import(AuthorizationServerSecurityConfiguration.class)
//@EnableResourceServer
@ControllerRegister
//@PropertySource("classpath:myApplication.properties")
public class LearnSpringConfig {


    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource driverDataSource = new DruidDataSource();
        driverDataSource.setUrl("jdbc:postgresql://localhost:5432/postgres?characterEncoding=utf-8");
        driverDataSource.setUsername("postgres");
        driverDataSource.setPassword("123456");
        driverDataSource.setDriver(new Driver());
        driverDataSource.setQueryTimeout(5);
        driverDataSource.setValidationQueryTimeout(0);
        return driverDataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setPlugins(new PaginationStatementHandlerInterceptor());
        return factoryBean.getObject();
    }
    @Bean
    public SqlSessionFactory newSqlSessionFactory() throws Exception {
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(dataSource());
        factoryBean.setPlugins(new PaginationStatementHandlerInterceptor());
        return factoryBean.getObject();
    }


    @Bean
    public PlatformTransactionManager platformTransactionManager() throws SQLException {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource());
        return dataSourceTransactionManager;
    }


    @Bean
    @Primary
    public InMemoryClientDetailsService inMemoryClientDetailsService(){
        InMemoryClientDetailsService inMemoryClientDetailsService = new InMemoryClientDetailsService();
        BaseClientDetails baseClientDetails = new BaseClientDetails();
        baseClientDetails.setClientId("zsc");
        baseClientDetails.setClientSecret("{bcrypt}"+new BCryptPasswordEncoder().encode("123456"));
        Map<String, BaseClientDetails> map = new HashMap<String, BaseClientDetails>();
        map.put("zsc",baseClientDetails);
        inMemoryClientDetailsService.setClientDetailsStore(map);

        return inMemoryClientDetailsService;
    }


    @Bean
    public UserDetailsService userDetailsService(){

        Collection<? extends GrantedAuthority> authorities = new ArrayList<SimpleGrantedAuthority>();
        SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("USER");
        ((ArrayList<GrantedAuthority>) authorities).add(simpleGrantedAuthority);

        User user = new User("zsc","{bcrypt}"+new BCryptPasswordEncoder().encode("123456"),authorities);
        Collection<UserDetails> users = new ArrayList<UserDetails>();
        ((ArrayList<UserDetails>) users).add(user);
        return new InMemoryUserDetailsManager(users);
    }

    public AuthorizationServerConfigurerAdapter authorizationServerConfigurerAdapter(){
        return new AuthorizationServerConfigurerAdapter();
    }




}
